/**
 * huize Service Inc
 * All Rights Reserved @2018
 */
package com.huize.zhike.framework.common.page;

import com.huize.ladon.apm.common.common.PairKV;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

/**
 * 分页条件（带排序）
 *
 * @author tianyuliang
 * @version $Id: PageCondition.java, v0.1 2018/10/15
 */
public class PageCondition {

    /**
     * 当前页开始位置，注意是索引，从0开始
     */
    @Getter
    private int offset = 0;

    /**
     * 页码索引，从1开始
     */
    @Getter
    private int pageNum = 1;

    /**
     * 每页大小
     */
    @Getter
    private int pageSize = 10;

    /**
     * 排序字符串
     **/
    @Getter
    @Setter
    private String sort;

    private PageCondition() {
    }

    public void updatePageSize(int pageSize) {
        if (pageSize <= 0) {
            throw new IllegalArgumentException("pageSize can't less than zero");
        }
        this.pageSize = pageSize;
    }

    public void updateOffset(int offset) {
        this.offset = offset;
        this.pageNum = (offset + 1) / pageSize + ((offset + 1) % pageSize == 0 ? 0 : 1);
    }

    public void updatePageNum(int pageNum) {
        this.pageNum = pageNum;
        this.offset = (pageNum - 1) * pageSize;
    }

    /**
     * 建造器
     */
    public static class Builder {
        private static final String ASC = "ASC";
        private static final String DESC = "DESC";
        private List<PairKV<String, String>> pairs = new ArrayList<>();
        private PageCondition pageCondition = new PageCondition();

        /**
         * 偏移量
         *
         * @param offset
         * @return
         */
        public Builder offset(int offset) {
            if (offset > 0) {
                pageCondition.offset = offset;
            }
            return this;
        }

        /**
         * 当前页码
         *
         * @param pageNum
         * @return
         */
        public Builder pageNum(int pageNum) {
            if (pageNum >= 1) {
                pageCondition.pageNum = pageNum;
            }
            return this;
        }

        /**
         * 每页条数
         *
         * @param pageSize
         * @return
         */
        public Builder pageSize(int pageSize) {
            if (pageSize > 0) {
                pageCondition.pageSize = pageSize;
            }
            return this;
        }

        /**
         * 字段升序
         *
         * @param sortColumn
         * @return
         */
        public Builder asc(String sortColumn) {
            if (sortColumn != null) {
                pairs.add(new PairKV<>(sortColumn, ASC));
            }
            return this;
        }

        /**
         * 字段降序
         *
         * @param sortColumn
         * @return
         */
        public Builder desc(String sortColumn) {
            if (sortColumn != null) {
                pairs.add(new PairKV<>(sortColumn, DESC));
            }
            return this;
        }

        /**
         * 构造PageCondition实例
         *
         * @return
         */
        public PageCondition build() {
            StringBuilder sortBuilder = new StringBuilder();
            for (PairKV<String, String> pair : pairs) {
                sortBuilder.append(",").append(pair.getKey()).append(" ").append(pair.getValue());
            }
            if (sortBuilder.length() > 0) {
                pageCondition.sort = sortBuilder.substring(1);
            }

            if (pageCondition.sort == null) {//默认order by 1
                pageCondition.sort = " 1 ";
            }
            if (pageCondition.offset > 0) {
                pageCondition.pageNum = (pageCondition.offset + 1) / pageCondition.pageSize + ((pageCondition.offset + 1) % pageCondition.pageSize > 0 ? 1 : 0);
                if (pageCondition.pageNum < 0) {
                    pageCondition.pageNum = 1;
                }
            } else if (pageCondition.offset == 0 && pageCondition.pageNum >= 0) {
                pageCondition.offset = (pageCondition.pageNum - 1) * pageCondition.pageSize;
            }
            return pageCondition;
        }

    }

}